package celiasoft.itasalib.query.resultparser;

import java.net.MalformedURLException;
import java.net.URL;
import java.text.DateFormat;
import java.text.DateFormatSymbols;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import android.util.Log;
import celiasoft.itasalib.structures.EpisodeData;
import celiasoft.itasalib.structures.SubsVersion;

public class W3CParsingHandler {

	private static final String TAG = "itasalib.parser.ParsingHandler";
	
	public static int parseIntValue(Element e, String tagName) {
		
		String strValue = DomHandler.getValue(e, tagName);
		
		return Integer.parseInt((strValue == null?"-1":strValue));
	}
	
	public static int parseIntValue(Document d, String tagName) {
		
		String strValue = DomHandler.getValue(d, tagName);
		
		return Integer.parseInt((strValue == null?"-1":strValue));
	}

	public static Date parseSimpleDateValue(Element e, String tagName){

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date value = null;
		
		String strValue = DomHandler.getValue(e,tagName);
		if(strValue != null){
			try {
				value = (Date) sdf.parse(strValue);
			}catch (ParseException e1) {
				e1.printStackTrace();
				Log.e(TAG, "Unable to parse date value.");
			}
		}
		
		return value;
			
	}
	
	
	
	public static Date parseW3CDateValue(Element e, String tagName){

		Date value = null;
		
		@SuppressWarnings("serial")
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"){ 
		    public Date parse(String source,ParsePosition pos) {    
		        return super.parse(source.replaceFirst(":(?=[0-9]{2}$)",""),pos);
		    }
		};
		
		String strValue = DomHandler.getValue(e,tagName);
		if(strValue != null){
			try {
				value = (Date) df.parse(strValue);
			}catch (ParseException e1) {
				e1.printStackTrace();
				Log.e(TAG, "Unable to parse date value.");
			}
		}
		
		return value;
			
	}
	
	public static URL parseURLValue(Element e, String tagName){

		URL value = null;
		
		String strValue = DomHandler.getValue(e,tagName);
		if(strValue != null){
			try {
				value = new URL(strValue);
				
			}catch (MalformedURLException ex) {
				ex.printStackTrace();
				Log.e(TAG, "Unable to parse URL value.");
			}
		}
		
		return value;
			
	}

	public static Date parseTime24hValue(Element e, String tagName) {
		
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
		Date value = null;
		
		String strValue = DomHandler.getValue(e,tagName);
		if(strValue != null){
			try {
				value = (Date) sdf.parse(strValue);
			}catch (ParseException e1) {
				e1.printStackTrace();
				Log.e(TAG, "Unable to parse time value.");
			}
		}
		
		return value;
	}

	public static EpisodeData parseEpisodeDataValue(Element e, String tagName) {
		
		EpisodeData value = null;
		
		String strValue = DomHandler.getValue(e,tagName);
		if(strValue != null){
			try {
				value = EpisodeData.parse(strValue);
				
			}catch (MalformedEpisodeDataException ex) {
				ex.printStackTrace();
				Log.e(TAG, "Unable to parse episode data value.");
			}
		}
		
		return value;
			
	}

	/**
	 * 
	 * @param e
	 * @param tagName
	 * @return an integer that represents a week day's number, from Monday (0) to Sunday (6), or -1.
	 */
	public static int parseStringDayValue(Element e, String tagName) {
				
		if(tagName != null){
		
			String[] weekdays = new DateFormatSymbols().getWeekdays(); // Get day names
			for(int i = 0; i < weekdays.length; i++){
				if(weekdays[i].compareToIgnoreCase(tagName) == 0){
					return (i == 0)?6:(i-1);
				}
			}
		}
		return -1;
	}
	
	public static <T> List<T> parseList(Element e, String parentTagName, ElementParser<T> parser) {
		
		ArrayList<T> res = new ArrayList<T>();
		
		NodeList actors =  e.getElementsByTagName(parentTagName);
		
		if(actors.getLength() < 1 
				|| !actors.item(0).hasChildNodes()){
			return res;
		}
		
		NodeList nodes = actors.item(0).getChildNodes();
		
		if(nodes.getLength() > 0){
			for(int i = 0; i < nodes.getLength(); i++){
				Node n = nodes.item(i);
				
				T a = parser.parseElement(n);
				if(a != null){
					res.add(a);
				}
			}
		}
		
		
		
		return res;
	}
	
	public interface ElementParser<T>{
		public T parseElement(Node n);
	}

	public static SubsVersion parseSubVersionValue(Element e, String tagName) {

		SubsVersion value = null;
		
		String strValue = DomHandler.getValue(e,tagName);
		if(strValue != null){
			try {
				value = SubsVersion.parse(strValue);
			}catch (MalformedSubsVersionException ex) {
				ex.printStackTrace();
				Log.e(TAG, "Unable to parse SubsVersion value.");
			}
		}
		
		return value;
	}

	public static boolean parseBooleanValue(Element e, String tagName) {
		boolean value = false;
		
		String strValue = DomHandler.getValue(e,tagName);
		if(strValue != null){	
			value = ("1".compareToIgnoreCase(tagName) == 0);
		}
		
		return value;
	}

	
}
